package com.dfch.auto.appium.utils;

import org.apache.log4j.PropertyConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

public class AppiumUtils extends EnvUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(AppiumUtils.class);

    private static final ConcurrentHashMap<String, Process> processCache = new ConcurrentHashMap<>();

    /**
     * @param devices
     * @param startPort
     */

    public static void createAppiumServers(List<String> devices, Integer startPort) throws IOException {
        try {

            CountDownLatch cdl = new CountDownLatch(devices.size());
            AtomicInteger num = new AtomicInteger(startPort);
            List<String> cmds = new ArrayList<String>();
//            cmds.add("cmd.exe");
//            cmds.add("/k");

            for (String device : devices) {
                int port = num.addAndGet(1);
                int bp = port + 1000;
                int sp = port + 2000;
                String appiumHome = getEnv("APPIUM_HOME");
                String appiumCMD = "start /b " + appiumHome + "\\appium.cmd -a  127.0.0.1 -p " + port + " -bp " + bp + " --chromedriver-port " + sp + " -U " + device + " --session-override";
                LOGGER.info("appium 环境准备命令{}", appiumCMD);
                cmds.add(appiumCMD);
//                cmds.add("/k");

            }

            File file = new File("D:\\appium_startup.bat");
            FileOutputStream fo = new FileOutputStream(file);
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fo));
            for (String cmd : cmds) {
                writer.write(cmd);
                writer.write("\r\n");
            }

            writer.flush();
            writer.close();
            Process process = Runtime.getRuntime().exec("D:\\appium_startup.bat");
            InputStream in = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line = null;
            while ((line = reader.readLine()) != null) {
                LOGGER.info("appium进程:{}", line);
            }

            in = process.getErrorStream();
            reader = new BufferedReader(new InputStreamReader(in));
            while ((line = reader.readLine()) != null) {
                LOGGER.info("appium进程ERROR:{}", line);
            }
        } catch (Exception e) {
            LOGGER.error("appium服务器启动发生不可预期的异常，请稍后再试!");
            throw e;
        }
    }

    /**
     * @param ip
     * @param port
     * @param bootstrapPort
     * @param driverPort
     * @param udid
     */

    public static void createAppiumServer(String ip, Integer port, Integer bootstrapPort, Integer driverPort, String udid) {
        hasEnv("APPIUM_HOME");

        Process process = null;
        try {
            String appiumHome = getEnv("APPIUM_HOME");
            String appiumCMD = appiumHome + "\\appium.cmd -a " + ip + " -p " + port + " -bp " + bootstrapPort + " --chromedriver-port " + driverPort + " -U " + udid + " --session-override";
            LOGGER.debug("appium 启动命令:{}", appiumCMD);
            List<String> list = new ArrayList<>();
            list.add("start");
            list.add("cmd.exe");
            list.add("/k");
            list.add(appiumCMD);

            ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/k", "start /b " + appiumCMD, "/k", "/b");
            process = processBuilder.start();
//            processBuilder.start();
//            process = Runtime.getRuntime().exec(appiumCMD);
            processCache.put(udid, process);
            InputStream in = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line = null;
            while ((line = reader.readLine()) != null) {
                LOGGER.info("appium创建进程:{}", line);
            }

            in = process.getErrorStream();
            reader = new BufferedReader(new InputStreamReader(in));
            while ((line = reader.readLine()) != null) {
                LOGGER.info("appium创建进程ERROR:{}", line);
            }
        } catch (IOException e) {
            LOGGER.error("创建Appium 服务端失败:", e);
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
    }


    public static void createAppiumServer2(String ip, Integer port, Integer bootstrapPort, Integer driverPort, String udid) {
        hasEnv("APPIUM_HOME");

        Process process = null;
        try {
            String appiumCMD = "java  " + AppiumStarter.class.getName() + " " + ip + " " + port + " " + bootstrapPort + " " + driverPort + " " + udid;
            LOGGER.debug("appium 启动命令:{}", appiumCMD);
            ProcessBuilder processBuilder = new ProcessBuilder("java", AppiumStarter.class.getName(), ip, port + "", bootstrapPort + "", driverPort + "");
            process = processBuilder.start();
            InputStream in = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line = null;
            while ((line = reader.readLine()) != null) {
                LOGGER.info("appium创建进程:{}", line);
            }

            in = process.getErrorStream();
            reader = new BufferedReader(new InputStreamReader(in));
            while ((line = reader.readLine()) != null) {
                LOGGER.info("appium创建进程ERROR:{}", line);
            }
        } catch (IOException e) {
            LOGGER.error("创建Appium 服务端失败:", e);
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
    }


    public static void destoryAll(List<String> devices, Integer startPort) {
        if (CollectionUtils.isEmpty(devices)) {
            return;
        }
        for (String device : devices) {
            try {
                if (processCache.contains(device)) {
                    Process process = processCache.get(device);
                    if (process.isAlive()) {
                        process.destroy();
                    }
                }
                Process process = Runtime.getRuntime().exec("netstat -aon | findstr " + (++startPort));
                InputStream in = process.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                String line = reader.readLine();
                if (StringUtils.isEmpty(line)) {
                    throw new RuntimeException("没有找到设备" + device + "的appium服务器!");
                }
                String pid = line.substring(-5, -1);
                process = Runtime.getRuntime().exec("taskkill  /pid " + pid +" /t /f");
                in = process.getInputStream();
                reader = new BufferedReader(new InputStreamReader(in));
                while ((line = reader.readLine()) != null) {
                    LOGGER.info("appium关闭进程:{}", line);
                }

                in = process.getErrorStream();
                reader = new BufferedReader(new InputStreamReader(in));
                while ((line = reader.readLine()) != null) {
                    LOGGER.info("appium关闭进程:{}", line);
                }

            } catch (Exception e) {
                LOGGER.error("退出appium失败:{}", device,e);
                continue;
            }
        }

    }

    public static void main(String[] args) {

        PropertyConfigurator.configure("D://workspace/ms/client/appium/src/main/resources/log4j.properties");


        List<String> devices = new ArrayList<>();
        devices.add("test");
        devices.add("test1");

        try {
            createAppiumServers(devices, 6000);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
